Skip to content

Commit 261761b

Browse files
authored
ensure metadata is dict in all cases (#6646)
1 parent f4c51a5 commit 261761b

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

kitsune/products/admin.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Any
22

3+
from django import forms
34
from django.contrib import admin
45
from django.db.models.query import QuerySet
56
from django.http import HttpRequest
@@ -14,6 +15,24 @@
1415
)
1516

1617

18+
class DictOnlyJSONField(forms.JSONField):
19+
def to_python(self, value):
20+
if value in self.empty_values:
21+
return {} # Convert an empty input value into an empty dict.
22+
result = super().to_python(value)
23+
if not isinstance(result, dict):
24+
raise forms.ValidationError("Value must be a JSON object (dict).")
25+
return result
26+
27+
28+
class TopicAdminForm(forms.ModelForm):
29+
metadata = DictOnlyJSONField(required=False)
30+
31+
class Meta:
32+
model = Topic
33+
fields = "__all__"
34+
35+
1736
class ArchivedFilter(admin.SimpleListFilter):
1837
title = "Archived status"
1938
parameter_name = "is_archived"
@@ -71,6 +90,8 @@ def parent(obj):
7190
def get_products(obj):
7291
return ", ".join([p.title for p in obj.products.all()])
7392

93+
form = TopicAdminForm
94+
7495
parent.short_description = "Parent" # type: ignore
7596
get_products.short_description = "Products" # type: ignore
7697

kitsune/products/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ def save(self, *args, **kwargs):
182182
cache_key = f"hierarchical_topics_{product.slug}"
183183
cache.delete(cache_key)
184184

185+
# Ensure that the "metadata" field is a dict.
186+
if self.metadata is None:
187+
self.metadata = {}
188+
elif not isinstance(self.metadata, dict):
189+
raise ValueError('The "metadata" field must be a dict.')
190+
185191
super().save(*args, **kwargs)
186192
self._topic_is_archived = self.is_archived
187193

0 commit comments

Comments
 (0)